import { DataFormatError } from '../constant/err.type.ts'
import { validate, joiErrHandle } from '../constant/validate.err.ts'

export const validator = (rules: any) => {
  return async (ctx: any, next: any) => {
    try {
      ctx.verifyParams(rules)
    } catch (error) {
      DataFormatError.error = validate(error)
      return ctx.app.emit('error', DataFormatError, ctx)
    }
    await next()
  }
}

// 至少传一个参数
export const atLeastOneParam = (array: string[]) => {
  return async (ctx: any, next: any) => {
    const res = array.filter((key: string) =>
      Object.prototype.hasOwnProperty.call(ctx.request.body, key),
    )
    if (!res.length) {
      return ctx.echo({ msg: array.join(',') + ' 至少传一个参数' })
    }
    await next()
  }
}

/**
 * 使用 Joi 校验请求体数据，并在验证失败时触发错误处理流程。
 * @param schema Joi 校验规则对象，用于验证请求体。
 * @returns 返回一个中间件函数，在验证失败时将错误信息传递给错误处理器。
 */
export const validateJoi = (schema: any) => {
  return async (ctx: any, next: any) => {
    const method = ctx.request.method.toUpperCase()
    let source
    if (method === 'GET' || method === 'DELETE') {
      source = ctx.request.query
    } else {
      source = ctx.request.body
    }
    const { error } = schema.validate(source, {
      abortEarly: false, // 返回所有错误而不是第一个错误
      stripUnknown: true, // 自动去除未知字段
    })
    if (error) {
      DataFormatError.msg = await joiErrHandle(error)
      return ctx.app.emit('error', DataFormatError, ctx)
    }
    await next()
  }
}
